package com.campus.shop.exception;


import com.campus.shop.common.Errors;
import com.campus.shop.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;

/**
 * @Description:全局异常处理
 * @Author: xr
 * @Date: 2023/3/6 17:12
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 如果捕获的是service抛出的异常，则调用该方法
     * @param e
     * @return
     */
    @ExceptionHandler(ServiceException.class)
    public Result handler(ServiceException e){
        log.error("未知异常！异常处在：[{}] , 原因是：[{}]", e.getMessage());
        //这里先判断拦截到的Exception是不是我们自定义的异常类型
        if(e instanceof ServiceException){
            return Result.error(e.getCode(), e.getMessage());
        }
        //如果拦截的异常不是我们自定义的异常(例如：数据库主键冲突)
        return Result.error(500,"系统错误");
    }

    /**
     * 运行异常
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public Result handler(RuntimeException e){
        log.error("未知异常！异常处在：[{}] , 原因是：[{}]", e.getMessage());
        return Result.error(500,"运行异常");
    }


    /**
     * 空指针
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    public Result exceptionHandler(NullPointerException e) {
        log.error("发生空指针异常！异常处在：[{}] , 原因是：[{}]", e.getMessage());
        return Result.error(Errors.BODY_NOT_MATCH);

    }

    /**
     * 未知异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Result exceptionHandler(Exception e) {
        log.error("未知异常！异常处在：[{}] , 原因是：[{}]", e.getMessage());
        return Result.error(500, "系统错误");
    }

    /**
     * 用于捕获@RequestBody类型参数触发校验规则抛出的异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result handleValidException(MethodArgumentNotValidException e) {
        StringBuilder sb = new StringBuilder();
        List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
        if (!CollectionUtils.isEmpty(allErrors)) {
            for (ObjectError error : allErrors) {
                sb.append(error.getDefaultMessage()).append(";");
            }
        }
        return Result.error(500, sb.toString());
    }

    /**
     * 缺少请求参数异常
     * @param ex HttpMessageNotReadableException
     * @return
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public Result handleHttpMessageNotReadableException(MissingServletRequestParameterException ex) {
        log.error("缺少请求参数，{}", ex.getMessage());
        return Result.error(400, "参数错误");
    }




}
